package com.mida.bms.report.service.impl;


import com.mida.bms.report.entity.DocDefineSpaceConsumer;
import com.mida.bms.report.entity.DocStructDefinitionSpace;
import com.mida.bms.report.mapper.DocDefineSpaceConsumerMapper;
import com.mida.bms.report.mapper.DocStructDefinitionSpaceMapper;
import com.mida.bms.report.mapper.DocStructTemplateInfoMapper;
import com.mida.bms.report.service.DocStructDefinitionSpaceService;
import com.mida.bms.report.service.SoidService;
import com.mida.bms.report.vo.*;
import com.mida.tool.common.result.ActionResult;
import com.mida.tool.common.result.BaseResult;
import com.mida.tool.common.result.ListResult;
import com.mida.tool.common.utils.CharTransFormUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <h1>结构化模板定义空间服务实现</h1>
 * <p>
 *
 * @author jian.li on 2021/3/30 16:59
 */
@Service
@Slf4j
@Transactional(value = "docTxManager", rollbackFor = Exception.class)
public class DocStructDefinitionSpaceServiceImpl extends BaseResult implements DocStructDefinitionSpaceService {

    @Autowired
    private DocStructDefinitionSpaceMapper docStructDefinitionSpaceMapper;

    @Autowired
    private DocDefineSpaceConsumerMapper docDefineSpaceConsumerMapper;

    @Autowired
    private DocStructTemplateInfoMapper docStructTemplateInfoMapper;

    //    @Autowired
//    private CMOIDGanerator cmoidGanerator;
//
//    @Autowired
//    private CMDtOidMapper cmDtOidMapper;
    @Autowired
    private SoidService soidService;
//
//    @Autowired
//    private IEmployeeInfoApi iEmployeeInfoApi;
//
//    @Autowired
//    private IBusinessUnitApi iBusinessUnitApi;

    /**
     * 1.添加定义空间
     *
     * @param vo
     * @return
     */
    @Override
    public ActionResult add(DocStructDefinitionSpaceVo vo) {

        if (vo.getStTempDefineSoid() != null) {
            log.info(vo.toString() + "不是一个新增,转到update");
            return update(vo);
        }

        log.info("开始添加定义空间: " + vo.toString());
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();

        try {
            if (StringUtils.isEmpty(vo.getStTempDefineName())) {
                buildBadRequestActionWarn(actionResult, "定义空间名称不能为空");
                return actionResult;
            }
            int count = docStructDefinitionSpaceMapper.countDefineSpaceName(vo.getStTempDefineName());
            if (count > 0) {
                buildBadRequestActionWarn(actionResult, "定义空间名称已存在");
                return actionResult;
            }

            DocStructDefinitionSpace entity = new DocStructDefinitionSpace();
            BeanUtils.copyProperties(vo, entity);
            entity.setPyCode(CharTransFormUtil.toPinyinSimple(vo.getStTempDefineName()));
            entity.setWbCode(CharTransFormUtil.toWubi(vo.getStTempDefineName()));


            Long soid = soidService.getSoid();
            entity.setStTempDefineSoid(soid);
            entity.setCreateDate(new Date());
            entity.setUpdateDate(new Date());
            entity.setIsDelete(0L);
            docStructDefinitionSpaceMapper.insert(entity);

            //国标
            soidService.insertOid(soid, 4);

            //添加定义空间用户数据
            addDefineSpaceConsumer(vo, entity);
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("添加定义空间异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "添加定义空间失败");
        } finally {
            stopWatch.stop();
            log.info("本次新增耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 2.更新定义空间
     *
     * @param vo
     * @return
     */
    @Override
    public ActionResult update(DocStructDefinitionSpaceVo vo) {

        log.info("开始更新定义空间: " + vo.toString());
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();
        try {
            if (vo.getStTempDefineSoid() == null) {
                buildBadRequestActionWarn(actionResult, "定义空间soid不能为空");
                return actionResult;
            }

            if (StringUtils.isEmpty(vo.getStTempDefineName())) {
                buildBadRequestActionWarn(actionResult, "定义空间名称不能为空");
                return actionResult;
            }
            int count = docStructDefinitionSpaceMapper.countDefineSpaceName(vo.getStTempDefineName());
            DocStructDefinitionSpace docStructDefinitionSpace = docStructDefinitionSpaceMapper.selectByPrimaryKey(vo.getStTempDefineSoid());
            if (count > 0 && !docStructDefinitionSpace.getStTempDefineName().equals(vo.getStTempDefineName())) {
                buildBadRequestActionWarn(actionResult, "定义空间名称已存在");
                return actionResult;
            }

            docStructDefinitionSpace.setStTempDefineName(vo.getStTempDefineName());
            docStructDefinitionSpace.setHospitalSoid(vo.getHospitalSoid());
            docStructDefinitionSpace.setExamServiceType(vo.getExamServiceType());
            docStructDefinitionSpace.setPyCode(CharTransFormUtil.toPinyinSimple(vo.getStTempDefineName()));
            docStructDefinitionSpace.setWbCode(CharTransFormUtil.toWubi(vo.getStTempDefineName()));
            docStructDefinitionSpace.setUpdateDate(new Date());
            //更新定义空间记录
            docStructDefinitionSpaceMapper.updateByPrimaryKeySelective(docStructDefinitionSpace);
            //删除原定义空间用户记录
            docDefineSpaceConsumerMapper.deleteByDefineSpaceSoid(vo.getStTempDefineSoid());
            //新增定义空间用户记录
            addDefineSpaceConsumer(vo, docStructDefinitionSpace);
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("更新定义空间异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "更新定义空间失败");
        } finally {
            stopWatch.stop();
            log.info("本次更新耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 3.定义空间名称重复性校验
     *
     * @param name
     * @param defineSpaceSoid
     * @return
     */
    @Override
    public ActionResult checkName(String name, Long defineSpaceSoid) {
        log.info("开始检查是否重名" + name);
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();

        try {
            if (StringUtils.isEmpty(name)) {
                buildBadRequestActionWarn(actionResult, "定义空间名称不能为空");
                return actionResult;
            }

            int count = docStructDefinitionSpaceMapper.countDefineSpaceName(name);
            //新增状态
            if (count > 0 && defineSpaceSoid == null) {
                buildBadRequestActionWarn(actionResult, "定义空间名称已存在");
                return actionResult;
            }
            //更新状态
            if (defineSpaceSoid != null) {
                DocStructDefinitionSpace docStructDefinitionSpace = docStructDefinitionSpaceMapper.selectByPrimaryKey(defineSpaceSoid);
                if (count > 0 && !name.equals(docStructDefinitionSpace.getStTempDefineName())) {
                    buildBadRequestActionWarn(actionResult, "定义空间名称已存在");
                    return actionResult;
                }
            }
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("检查是否重名异常", e);
            buildActionWarn(actionResult, "检查是否重名失败");
        } finally {
            stopWatch.stop();
            log.info("本次检查耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 4.删除定义空间
     *
     * @param defineSpaceSoid
     * @return
     */
    @Override
    public ActionResult delete(long defineSpaceSoid) {

        log.info("开始删除定义空间" + defineSpaceSoid);
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();
        try {
            DocStructDefinitionSpace docStructDefinitionSpace = docStructDefinitionSpaceMapper.selectByPrimaryKey(defineSpaceSoid);
            if (docStructDefinitionSpace.getStatus().longValue() == 149L && docStructDefinitionSpace.getIsDelete().longValue() == 0L) {
                buildBadRequestActionWarn(actionResult, "定义空间为启用状态,无法删除");
                return actionResult;
            }
            //删除定义空间
            docStructDefinitionSpaceMapper.deleteByPrimaryKey(defineSpaceSoid);
            //删除定义空间用户信息
            docDefineSpaceConsumerMapper.deleteByDefineSpaceSoid(defineSpaceSoid);
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("删除定义空间发送异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            buildActionWarn(actionResult, "删除定义空间失败");
        } finally {
            stopWatch.stop();
            log.info("本次删除耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 5.分页查询定义空间
     *
     * @param vo
     * @return
     */
    @Override
    public ListResult<PageResultVo<DocStructDefinitionSpaceVo>> findPage(DocStructDefinitionSpacePageVo vo) {
        log.info("开始分页查询,查询条件: " + vo.getSearchData());
        ListResult listResult = new ListResult();
        PageResultVo pageResultVo = new PageResultVo();
        Page page = new Page(vo.getCurrentPage(), vo.getPageSize());
        pageResultVo.setPage(page);
        StopWatch stopWatch = StopWatch.createStarted();
        List<DocStructDefinitionSpaceVo> list = null;

        try {
            DocStructDefinitionSpacePage npage = new DocStructDefinitionSpacePage(vo.getCurrentPage(), vo.getPageSize(), vo.getSearchData());
            int count = docStructDefinitionSpaceMapper.findPageCount(npage);
            if (count > 0) {
                page.setTotalCount(count);
                list = docStructDefinitionSpaceMapper.findPage(npage);
            } else {
                page.setTotalCount(count);
                list = new ArrayList<DocStructDefinitionSpaceVo>(0);
            }
            pageResultVo.setList(list);
            buildListSuccess(listResult, pageResultVo);
        } catch (Exception e) {
            list = new ArrayList<DocStructDefinitionSpaceVo>(0);
            pageResultVo.setList(list);
            log.error("分页查询定义空间发送异常", e);
            buildListWarn(listResult, "分页查询定义空间失败");
        } finally {
            stopWatch.stop();
            log.info("本次分页查询耗时:" + stopWatch.getTime() + "ms");
        }
        return listResult;
    }

    /**
     * 6.更改定义空间状态(启用,停用)
     *
     * @param status
     * @param defineSpaceSoid
     * @return
     */
    @Override
    public ActionResult updateStatus(Long status, Long defineSpaceSoid) {
        log.info("开始更改定义空间状态" + status);
        StopWatch stopWatch = StopWatch.createStarted();
        ActionResult actionResult = new ActionResult();

        try {
            if (status == null) {
                buildBadRequestActionWarn(actionResult, "定义空间状态不能为空");
                return actionResult;
            }
            if (defineSpaceSoid == null) {
                buildBadRequestActionWarn(actionResult, "定义空间soid不能为空");
                return actionResult;
            }
            int count = docStructTemplateInfoMapper.countDefineSpace(defineSpaceSoid);
            if (count > 0 && status.longValue() == 150L) {
                buildBadRequestActionWarn(actionResult, "定义空间已被引用,无法停用");
                return actionResult;
            }
            //更新定义空间状态
            DocStructDefinitionSpace docStructDefinitionSpace = new DocStructDefinitionSpace();
            docStructDefinitionSpace.setStTempDefineSoid(defineSpaceSoid);
            docStructDefinitionSpace.setStatus(status);
            docStructDefinitionSpace.setUpdateDate(new Date());
            docStructDefinitionSpaceMapper.updateByPrimaryKeySelective(docStructDefinitionSpace);
            //更新定义用户信息状态
            docDefineSpaceConsumerMapper.updateStatusByDefineSpaceSoid(status, defineSpaceSoid);
            buildActionSuccess(actionResult);
        } catch (Exception e) {
            log.error("更改定义空间状态异常", e);
            buildActionWarn(actionResult, "更改定义空间状态失败");
        } finally {
            stopWatch.stop();
            log.info("本次更改定义空间状态耗时:" + stopWatch.getTime() + "ms");
        }
        return actionResult;
    }

    /**
     * 7.获取单个定义空间
     *
     * @param defineSpaceSoid
     * @return
     */
    @Override
    public ListResult<DocStructDefinitionSpaceVo> get(long defineSpaceSoid) {
        log.info("开始获取定义空间:" + defineSpaceSoid);
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult<DocStructDefinitionSpaceVo> listResult = new ListResult<>();

//        try {
//            //获取定义空间
//            DocStructDefinitionSpaceVo docStructDefinitionSpaceVo = docStructDefinitionSpaceMapper.selectByDefineSpaceSoid(defineSpaceSoid);
//            List<DocDefineSpaceConsumerVo> docDefineSpaceConsumers = docDefineSpaceConsumerMapper.selectConsumersByDefineSpaceSoid(defineSpaceSoid);
//            docDefineSpaceConsumers.forEach(consumer ->{
//                com.chinatechstar.component.commons.result.ListResult<EmployeeInfoVo> employee = iEmployeeInfoApi.findOneBySoid(consumer.getDoctorSoid(), false);
//                //设置医生姓名
//                String doctorName  = employee.getData().getEmployeeName();
//                consumer.setDoctorName(doctorName);
//                //设置医生姓名与业务单元拼接的字段
//                com.chinatechstar.component.commons.result.ListResult<List<BusinessUnitVo>> unitList = iBusinessUnitApi.findBusinessUnitListByEmployeeSoid(consumer.getDoctorSoid(),null);
//                StringBuffer doctorNameWithUnitName = new StringBuffer(doctorName + "|");
//                List<BusinessUnitVo> data = unitList.getData();
//                for (int i = 0; i < data.size(); i++) {
//                    if(i == data.size() - 1){
//                        doctorNameWithUnitName.append(data.get(i).getBusinessUnitName());
//                    }else {
//                        doctorNameWithUnitName.append(data.get(i).getBusinessUnitName() + ",");
//                    }
//                }
//                consumer.setDoctorNameWithUnitName(doctorNameWithUnitName.toString());
//            });
//            docStructDefinitionSpaceVo.setDocDefineSpaceConsumerList(docDefineSpaceConsumers);
//
//            buildListSuccess(listResult, docStructDefinitionSpaceVo);
//        } catch (Exception e) {
//            log.error("获取单个定义空间发送异常", e);
//            buildListWarn(listResult, "获取定义空间失败");
//        } finally {
//            stopWatch.stop();
//            log.info("本次查询耗时:" + stopWatch.getTime() + "ms");
//        }
        return listResult;
    }

    /**
     * 8.查询所有定义空间
     *
     * @param searchData
     * @return
     */
    @Override
    public ListResult<List<DocStructDefinitionSpace>> findAll(String searchData,Long hospitalSoid) {
        log.info("开始查询所有定义空间,查询条件:" + searchData);
        ListResult listResult = new ListResult();
        StopWatch stopWatch = StopWatch.createStarted();
        List<DocStructDefinitionSpace> list = null;
        try {
            list = docStructDefinitionSpaceMapper.findAll(searchData,hospitalSoid);
            if (list == null) {
                list = new ArrayList<DocStructDefinitionSpace>(0);
            }
            buildListSuccess(listResult, list);
        } catch (Exception e) {
            log.error("查询所有定义空间异常", e);
            buildListWarn(listResult, "查询所有定义空间失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时:" + stopWatch.getTime() + "ms");
        }
        return listResult;
    }

    /**
     * 新增定义空间用户数据
     *
     * @param vo     定义空间vo
     * @param entity 带有已生成soid的定义空间entity
     */
    private void addDefineSpaceConsumer(DocStructDefinitionSpaceVo vo, DocStructDefinitionSpace entity) {
        List<DocDefineSpaceConsumerVo> list = vo.getDocDefineSpaceConsumerList();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                DocDefineSpaceConsumer docDefineSpaceConsumer = new DocDefineSpaceConsumer();
//                docDefineSpaceConsumer.setDefSpcConsumerSoid(cmoidGanerator.getSOID());
                docDefineSpaceConsumer.setDefSpcConsumerSoid(soidService.getSoid());
                docDefineSpaceConsumer.setStTempDefineSoid(entity.getStTempDefineSoid());
                docDefineSpaceConsumer.setDoctorSoid(list.get(i).getDoctorSoid());
                docDefineSpaceConsumer.setCreateDate(new Date());
                docDefineSpaceConsumer.setUpdateDate(new Date());
                docDefineSpaceConsumer.setIsDelete(0L);
                docDefineSpaceConsumer.setStatus(entity.getStatus());
                docDefineSpaceConsumerMapper.insert(docDefineSpaceConsumer);
            }
        }

    }

    /**
     * 11、根据定义空间soid查询定义空间基本信息
     *
     * @param defineSpaceSoid 定义空间soid
     * @return
     */
    @Override
    public ListResult<DocStructDefinitionSpaceVo> selectByDefineSpaceSoid(long defineSpaceSoid) {
        log.info("开始根据定义空间soid查询定义空间基本信息,查询条件:" + defineSpaceSoid);
        StopWatch stopWatch = StopWatch.createStarted();
        ListResult<DocStructDefinitionSpaceVo> listResult = new ListResult<>();
        if (StringUtils.isEmpty(String.valueOf(defineSpaceSoid))) {
            buildBadRequestListWarn(listResult, "定义空间soid不能为空");
        }
        try {
            //获取定义空间
            DocStructDefinitionSpaceVo docStructDefinitionSpaceVo = docStructDefinitionSpaceMapper.selectByDefineSpaceSoid(defineSpaceSoid);
            buildListSuccess(listResult, docStructDefinitionSpaceVo);
        } catch (Exception e) {
            log.error("根据定义空间soid查询定义空间基本信息", e);
            buildListWarn(listResult, "根据定义空间soid查询定义空间基本信息失败");
        } finally {
            stopWatch.stop();
            log.info("本次查询耗时:" + stopWatch.getTime() + "ms");
        }
        return listResult;
    }
}
